package maxinshiSomeipTool20.common.itfSafeSWT;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ControlAdapter;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import java.util.ArrayList;
import java.util.List;

/**
 * SWT 容器分割工具类：支持按行（高度占比）、按列（宽度占比）分割父容器
 */
public class SWTContainerSplitter {

    /**
     * 方法1：按行分割（1列N行）- 支持高度占比
     * @param parent 父容器（非null、未释放）
     * @param heightRatios 高度占比数组（长度=行数，总和需≈1.0，如 [0.3, 0.7] 表示2行，占比3:7）
     * @return 子容器列表（顺序：从上到下）
     * @throws IllegalArgumentException 参数非法时抛出（如父容器无效、占比数组异常）
     * @example List<Composite> composites = SWTContainerSplitter.createVerticalContainers(rightPanel, new float[]{0.3f, 0.5f, 0.2f});
     */
    public static List<Composite> createVerticalContainers(Composite parent, float[] heightRatios) {
        // 1. 参数合法性校验
        validateParams(parent, heightRatios);

        int rowCount = heightRatios.length;
        List<Composite> childContainers = new ArrayList<>(rowCount);

        // 2. 父容器布局：1列，垂直排列
        GridLayout parentLayout = new GridLayout(1, false);
        parentLayout.marginWidth = 0;    // 父容器左右内边距（可按需调整）
        parentLayout.marginHeight = 0;   // 父容器上下内边距
        parentLayout.verticalSpacing = 5;// 子容器之间的垂直间距（避免紧贴）
        parent.setLayout(parentLayout);

        // 3. 创建子容器（1列N行）
        for (int i = 0; i < rowCount; i++) {
            Composite child = new Composite(parent, SWT.NONE);
            // 子容器默认布局（方便后续添加控件）
            child.setLayout(new GridLayout(1, false));
            // 初始GridData（后续通过监听动态更新高度）
            GridData childGridData = new GridData(SWT.FILL, SWT.FILL, true, true);
            child.setLayoutData(childGridData);

            childContainers.add(child);
        }

        // 4. 监听父容器大小变化，动态调整子容器高度（核心：确保占比生效）
        parent.addControlListener(new ControlAdapter() {
            @Override
            public void controlResized(ControlEvent e) {
                if (parent.isDisposed()) return;

                // 父容器可用高度 = 总高度 - 上下内边距 - 子容器间总间距
                int parentAvailHeight = parent.getClientArea().height
                        - parentLayout.marginHeight * 2
                        - parentLayout.verticalSpacing * (rowCount - 1);

                // 按占比分配每个子容器的高度
                for (int i = 0; i < rowCount; i++) {
                    Composite child = childContainers.get(i);
                    if (child.isDisposed()) continue;

                    GridData childData = (GridData) child.getLayoutData();
                    // 计算子容器高度（占比 × 可用高度）
                    int childHeight = Math.max(50, (int) (parentAvailHeight * heightRatios[i]));// 最小高度50px避免过窄
                    childData.heightHint = childHeight;
                    child.setLayoutData(childData);
                }

                // 强制刷新布局
                parent.layout(true, true);
            }
        });

        // 初始触发一次布局（确保首次显示正确）
        parent.layout(true, true);
        return childContainers;
    }

    /**
     * 方法2：按列分割（1行N列）- 支持宽度占比
     * @param parent 父容器（非null、未释放）
     * @param widthRatios 宽度占比数组（长度=列数，总和需≈1.0，如 [0.2, 0.5, 0.3] 表示3列，占比2:5:3）
     * @return 子容器列表（顺序：从左到右）
     * @throws IllegalArgumentException 参数非法时抛出（如父容器无效、占比数组异常）
     */
    public static List<Composite> createHorizontalContainers(Composite parent, float[] widthRatios) {
        // 1. 参数合法性校验
        validateParams(parent, widthRatios);

        int colCount = widthRatios.length;
        List<Composite> childContainers = new ArrayList<>(colCount);

        // 2. 父容器布局：N列，水平排列
        GridLayout parentLayout = new GridLayout(colCount, false);
        parentLayout.marginWidth = 0;     // 父容器左右内边距（可按需调整）
        parentLayout.marginHeight = 0;    // 父容器上下内边距
        parentLayout.horizontalSpacing = 5;// 子容器之间的水平间距（避免紧贴）
        parent.setLayout(parentLayout);

        // 3. 创建子容器（1行N列）
        for (int i = 0; i < colCount; i++) {
            Composite child = new Composite(parent, SWT.NONE);
            // 子容器默认布局（方便后续添加控件）
            child.setLayout(new GridLayout(1, false));
            // 初始GridData（后续通过监听动态更新宽度）
            GridData childGridData = new GridData(SWT.FILL, SWT.FILL, true, true);
            child.setLayoutData(childGridData);

            childContainers.add(child);
        }

        // 4. 监听父容器大小变化，动态调整子容器宽度（核心：确保占比生效）
        parent.addControlListener(new ControlAdapter() {
            @Override
            public void controlResized(ControlEvent e) {
                if (parent.isDisposed()) return;

                // 父容器可用宽度 = 总宽度 - 左右内边距 - 子容器间总间距
                int parentAvailWidth = parent.getClientArea().width
                        - parentLayout.marginWidth * 2
                        - parentLayout.horizontalSpacing * (colCount - 1);

                // 按占比分配每个子容器的宽度
                for (int i = 0; i < colCount; i++) {
                    Composite child = childContainers.get(i);
                    if (child.isDisposed()) continue;

                    GridData childData = (GridData) child.getLayoutData();
                    // 计算子容器宽度（占比 × 可用宽度）
                    int childWidth = Math.max(80, (int) (parentAvailWidth * widthRatios[i]));// 最小宽度80px避免过窄
                    childData.widthHint = childWidth;
                    child.setLayoutData(childData);
                }

                // 强制刷新布局
                parent.layout(true, true);
            }
        });

        // 初始触发一次布局（确保首次显示正确）
        parent.layout(true, true);
        return childContainers;
    }
    
    /**
     * 新增方法1：将容器设置在父容器顶部，横向填满（水平最大）
     * @param container 需要设置的子容器
     */
    public static void setContainerToTop(Composite container) {
        // 验证容器有效性
        if (container == null || container.isDisposed()) {
            throw new IllegalArgumentException("容器不能为空或已释放");
        }

        // 获取父容器（必须存在）
        Composite parent = container.getParent();
        if (parent == null || parent.isDisposed()) {
            throw new IllegalArgumentException("容器必须有有效的父容器");
        }

        // 配置GridData：水平填满、垂直靠顶、不抢占垂直空间
        GridData gridData = new GridData(
                SWT.FILL,      // 水平方向：填满父容器（横向最大）
                SWT.TOP,       // 垂直方向：靠顶部对齐
                true,          // 水平抢占额外空间（确保宽度随父容器变化）
                false          // 不抢占垂直空间（仅占用自身内容高度）
        );
        
        // 应用布局数据
        container.setLayoutData(gridData);
        
        // 刷新父容器布局
        parent.layout(true, true);
    }

    /**
     * 新增方法2：将容器设置在父容器底部，横向填满（水平最大）
     * @param container 需要设置的子容器
     */
    public static void setContainerToBottom(Composite container) {
        // 验证容器有效性
        if (container == null || container.isDisposed()) {
            throw new IllegalArgumentException("容器不能为空或已释放");
        }

        // 获取父容器（必须存在）
        Composite parent = container.getParent();
        if (parent == null || parent.isDisposed()) {
            throw new IllegalArgumentException("容器必须有有效的父容器");
        }

        // 配置GridData：水平填满、垂直靠底、不抢占垂直空间
        GridData gridData = new GridData(
                SWT.FILL,      // 水平方向：填满父容器（横向最大）
                SWT.BOTTOM,    // 垂直方向：靠底部对齐
                true,          // 水平抢占额外空间（确保宽度随父容器变化）
                false          // 不抢占垂直空间（仅占用自身内容高度）
        );
        
        // 应用布局数据
        container.setLayoutData(gridData);
        
        // 刷新父容器布局
        parent.layout(true, true);
    }

    /**
     * 通用参数校验：父容器有效性 + 占比数组合法性
     */
    private static void validateParams(Composite parent, float[] ratios) {
        // 校验父容器
        if (parent == null || parent.isDisposed()) {
            throw new IllegalArgumentException("父容器不能为空或已释放（Disposed）");
        }

        // 校验占比数组（非空、长度≥1、无负占比、总和≈1.0）
        if (ratios == null || ratios.length == 0) {
            throw new IllegalArgumentException("占比数组不能为空或长度为0");
        }

        float ratioSum = 0;
        for (float ratio : ratios) {
            if (ratio <= 0 || ratio >= 1) {
                throw new IllegalArgumentException("单个占比必须在(0,1)之间（当前非法值：" + ratio + "）");
            }
            ratioSum += ratio;
        }

        // 允许占比总和有微小误差（±0.01），避免用户手动计算的精度问题
        if (Math.abs(ratioSum - 1.0f) > 0.01f) {
            throw new IllegalArgumentException("占比总和必须≈1.0（当前总和：" + ratioSum + "）");
        }
    }
}